#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Author: Spayder26 < spayder26 _at_ gmail _dot_ com >
# License: GPLv3

import getopt
from KThread import KThread as kthread
from time import sleep
from os import system, linesep, getenv, sep, getpid, kill, remove, mkdir
from os.path import exists, isfile, split as path_split, realpath, expandvars
from sys import exit as sys_exit, argv, exc_info
from ConfigParser import SafeConfigParser
from base64 import b64encode, b64decode
from commands import getoutput
from signal import signal
from traceback import extract_tb
from urllib import url2pathname

try:
    import pygtk
    pygtk.require("2.0")
except:
    pass
try:
    import gtk
    import pango
    import gtk.glade
    import gobject
except:
    sys_exit(1)

import sshtransmission as T
from selenelang import _ , available_langs, set_locale, get_locale, set_langfolder, get_langfolder
from selenesearch import available_search_engines, open_browser, set_tsearchfolder, get_tsearchfolder
from seleneconnection import *
from seleneconnectionmanager import *
from selenebrowsewindow import *

#Sharing reference of selenelang module
setcm_(_)
setc_(_)
setbw_(_)
setbwT(T)

__version__ = '0.2.3'

class LoadingDialog(object):
    def __init__(self,wTree):
        self.me = wTree
        self.widget = self.me.get_widget("loadingdialog")
        self.widget.connect("response",self.__response__)
        self.thread = None
        self.ok = False
        self.loop = None

    def start(self,thread=None,title=_("connectingtitle"),text=None):
        self.ok = True
        self.thread = thread
        self.me.get_widget("loadinglabel").set_text(str(text))
        self.me.get_widget("loadinglabel").set_property("visible",not text == None)
        self.me.get_widget("loadingbuttons").set_property("visible",not thread == None)
        self.widget.set_title(title)
        if self.loop == None:
            
            self.loop = kthread(target=self.__push).start()

    def stop(self):
        self.ok = False
        self.thread = None

    def __push(self):
        self.widget.show()
        while self.ok:
            gtk.gdk.threads_enter()
            self.me.get_widget("loadingbar").pulse()
            gtk.gdk.threads_leave()
            sleep(0.1)
        self.widget.hide()
        self.loop = None

    def __response__(self,widget,response):
        if not bool(response) and self.thread != None:
            self.thread.kill()
        self.ok = False

class Main(object):
    def __init__(self,torrentfiles=[]):
        self.torrentfiles = torrentfiles
        self.loading = True
        self.tqueue = []
        self.me = gtk.glade.XML(gladefile)
        self.ldialog = LoadingDialog(self.me)
        self.ldialog.start(text="Running application...")
        connection = Connection()
        self.tcontrol = ConnectionManager(self.me,self,connection)
        self.bcontrol = BrowseWindow(self.me,self,connection)
        self.__internationalize()
        self.tsearchboxeraseable = True
        self.incoming = "/"
        self.statedaemonbool = None
        self.stateconnectedbool = None
        self.stopingstartingdaemon = False
        

        #SIGNALS
        dic = {"on_window1_destroy" : self.__quit,
               "on_btnadd_clicked"  : self.__selector,
               "on_btnplay_clicked" : self.__start,
               "on_btnpause_clicked"  : self.__pause,
               "on_btnremove_clicked" : self.__askremove,
               "on_menuadd_activate"  : self.__selector,
               "on_menuplay_activate"   : self.__start,
               "on_menupause_activate"  : self.__pause,
               "on_menuremove_activate" : self.__askremove,
               "on_menuitem9_activate" : self.__selector,
               "on_menuitem6_activate" : self.__start,
               "on_menuitem7_activate" : self.__pause,
               "on_menuitem8_activate" : self.__askremove,
               "on_menudirectory_activate"   : self.__browseincoming,
               "on_imagemenuitem5_activate"  : self.__quit,
               "on_menupreferences_activate" : self.__muestraprefs,
               "on_opscerrar_activate" : self.__opscerrar,
               "on_opsbrowse_clicked"  : self.__opsbrowse,
               "on_opsfolder_changed"  : self.__opsmanualbrowse,
               "on_opsfolder_button_press_event" : self.__opsfolderclick,
               "on_spinbutton1_value_changed" : self.__portspin,
               "on_spinbutton2_value_changed" : self.__ldownspin,
               "on_spinbutton3_value_changed" : self.__lupspin,
               "on_spinbutton4_value_changed" : self.__timeoutspin,
               "on_spinbutton5_value_changed" : self.__sshalivespin,
               "on_checkbutton1_toggled" : self.__cryptcheck,
               "on_checkbutton2_toggled" : self.__pexcheck,
               "on_checkbutton3_toggled" : self.__upnpcheck,
               "on_checkbutton4_toggled" : self.__statuscheck,
               "on_checkbutton5_toggled" : self.__showsearchbox,
               "on_logindialog_response" : self.__logindialog_response,
               "on_menureconnect_activate"   : self.__logindialog_show,
               "on_imagemenuitem10_activate" : self.__muestrabout,
               "on_aboutdialog1_response"    : self.__aboutresponse,
               "on_aboutdialog1_delete_event"  : self.__destroyevent,
               "on_window2_delete_event"       : self.__destroyevent,
               "on_logindialog_delete_event"   : self.__destroyevent,
               "on_loadingdialog_delete_event" : self.__destroyevent,
               "on_combobox1_changed"  : self.__changebtnvisibility,
               "on_combobox2_changed"  : self.__changelang,
               "on_menuitem3_activate" : self.__startdaemon,
               "on_menuitem5_activate" : self.__stopdaemon,
               "on_button3_clicked"    : self.__torrentsearchbutton,
               "on_tsearchbox_focus_in_event"  : self.__eraseabletsearchin,
               "on_tsearchbox_focus_out_event" : self.__eraseabletsearchout,
               "on_tsearchbox_changed"  : self.__tsearchchange,
               "on_tsearchbox_activate" : self.__torrentsearchbutton,
               "on_window1_focus_in_event"  : self.__window_twink_end,
               "on_combobox4_changed"       : self.__connection_dialog_protocol_changed,
               "on_menudisconnect_activate" : self.__disconnect,
               "on_notebook2_switch_page" : self.__changepage,
               }
        self.me.signal_autoconnect(dic)
        self.stid = None
        self.stcontext = self.me.get_widget("statusbar1").get_context_id("main")
        self.mainStatus(_("disconnected"))
        try:
            self.icon_up    = self.me.get_widget("window1").render_icon(gtk.STOCK_GO_UP, gtk.ICON_SIZE_MENU)
            self.icon_down  = self.me.get_widget("window1").render_icon(gtk.STOCK_GO_DOWN, gtk.ICON_SIZE_MENU)
            self.icon_pause = self.me.get_widget("window1").render_icon(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU)
            self.icon_help  = self.me.get_widget("window1").render_icon(gtk.STOCK_HELP, gtk.ICON_SIZE_MENU)
            self.icon_find  = self.me.get_widget("window1").render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU)
            self.icon_info  = self.me.get_widget("window1").render_icon(gtk.STOCK_INFO, gtk.ICON_SIZE_MENU)
            self.icon_error = self.me.get_widget("window1").render_icon(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_MENU)
        except:
            pass

        self.pthread_running = False
        self.pthread_time = 0
        self.refresh_time = 0

        self.manualbrowse_time = 0
        self.manualbrowse_running = False
        
        self.currentpage = 0

        self.spinvalues = [None,None,None,None,None]

        self.options_setted = False
        self.prop_timeout = 1500 # Timeout en milisegundos

        self.hostpath = []
        self.__initialize_combobox1()
        self.__initialize_combobox2()
        self.__initialize_combobox3()
        self.__initialize_combobox4()

        default_options = {
                           "showtimeout" : "1",
                           "showsearchbox" : "1",
                           "timeout"     : "5000",
                           "sshalive"    : "0",
                           "buttonstyle" : "1",
                           "language"    : get_locale(),
                           "protocol"    : "-1",
                           }

        self.config_file = configfolder+sep+"config.cfg"
        self.options = SafeConfigParser(default_options)
        self.me.get_widget("notebook2").set_sensitive(False)
        self.__window1_show()

        showlogin = True
        self.ldialog.stop()
        if exists(self.config_file):
            self.options.read(self.config_file)
            self.__internationalize(self.options.get("DEFAULT","language"))
            self.__changebtnvisibility()
            self.me.get_widget("searchbox").set_property("visible",bool(int(self.options.get("DEFAULT","showsearchbox"))))
            a = self.options.getint("DEFAULT","protocol")
            if a ==0:
                self.new_session(protocol=a)
                showlogin=False
            elif a ==1:
                if self.options.has_section("SSH"):
                    if self.options.getboolean("SSH","remenber"):
                        self.new_session(self.options.get("SSH","host"),
                                         self.options.get("SSH","user"),
                                         b64decode(self.options.get("SSH","password")),
                                         int(self.options.getfloat("SSH","port")),
                                         self.options.getboolean("SSH","remenber"),
                                         protocol=a)
                        showlogin=False
                else:
                    self.options.set("DEFAULT","protocol","-1")

        if showlogin:
            self.__logindialog_show()
    
    def __changepage(self,widget,pointer,index):
        self.currentpage = index

    def __connection_dialog_protocol_changed(self,widget):
        a = widget.get_active()
        if a==0:
            self.me.get_widget("logintable").set_sensitive(False)
        elif a==1:
            ip = "localhost"
            port = 22.
            user = getenv("USER")
            passw = ""
            remenber = False
            if self.options.has_section("SSH"):
                ip = self.options.get("SSH","host")
                user = self.options.get("SSH","user")
                passw = b64decode(self.options.get("SSH","password"))
                port = self.options.getfloat("SSH","port")
                remenber = self.options.getboolean("SSH","remenber")
            self.me.get_widget("loginhost").set_text(ip)
            self.me.get_widget("loginuser").set_text(user)
            self.me.get_widget("loginpassw").set_text(passw)
            self.me.get_widget("loginport").set_value(port)
            self.me.get_widget("loginremenber").set_active(remenber)

            self.me.get_widget("logintable").set_sensitive(True)

    def __window_twink_end(self,*args):
        if self.me.get_widget("window1").get_urgency_hint():
            self.me.get_widget("window1").set_urgency_hint(False)

    def __eraseabletsearchin(self,*args):
        if self.tsearchboxeraseable and not self.loading:
            self.tsearchboxeraseable = False
            self.me.get_widget("tsearchbox").set_text("")
        return False

    def __eraseabletsearchout(self,*args):
        if not self.tsearchboxeraseable and not self.loading and len(self.me.get_widget("tsearchbox").get_text())==0:
            self.tsearchboxeraseable = True
            self.me.get_widget("tsearchbox").set_text(_("tsearchbox"))
            self.me.get_widget("button3").set_sensitive(False)
        return False

    def __tsearchchange(self,*args):
        if not self.tsearchboxeraseable:
            self.me.get_widget("button3").set_sensitive(len(self.me.get_widget("tsearchbox").get_text())>0)

    def __internationalize(self,lang=None):
        if lang!=None:
            set_locale(lang)

        #labels
        for i,x in ((("label1","toolbutton2"),_("resumelabel")),
                    (("label14",),_("hostlabel")),
                    (("label17",),_("portlabel")),
                    (("label15",),_("usernamelabel")),
                    (("label16",),_("passwordlabel")),
                    (("loginremenber",),_("remenberpassword")),
                    (("label2",),_("interfacelabel")),
                    (("label3",),_("connectionlabel")),
                    (("checkbutton4",),_("showconnectiontimeout")),
                    (("checkbutton5",),_("showsearchbox")),
                    (("label12",),_("connectiontimeout")),
                    (("label21",),_("connectionalivetimeout")),
                    (("label21",),_("keepalivetimeout")),
                    (("label13","label32"),_("seconds")),
                    (("label18",),_("buttonvisibility")),
                    (("label19",),_("language")),
                    (("checkbutton1",),_("requirecrypt")),
                    (("checkbutton2",),_("enablepex")),
                    (("checkbutton3",),_("enableupnp")),
                    (("label8",),_("incomingfolder")),
                    (("label10",),_("findincoming")),
                    (("label9",),_("portnumber")),
                    (("label5",),_("downloadlimit")),
                    (("label4",),_("uploadlimit")),
                    (("label11",),_("optionsettedonnextconnection")),
                    (("label20",),_("clientconfig")),
                    (("label23",),_("noconfigfile")),
                    (("label27",),_("alltab")),
                    (("label30",),_("pausedtab")),
                    (("label28",),_("downloadingtab")),
                    (("label29",),_("uploadingtab")),
                    (("label31",),_("finishedtab")),
                    (("label33",),_("zeromeansdisabled")),
                    (("loadinglabel",),_("connectinglabel")),
                    ):
                        #(("label21",),_("notimplemented")),
            for j in i:
                self.me.get_widget(j).set_label(x)

        #windows
        for i,x in ((("window2",),_("optiondialogtitle")),
                    (("logindialog",),_("logindialogtitle")),
                    (("loadingdialog",),_("connectingtitle")),
                   ):
            for j in i:
                self.me.get_widget(j).set_title(x)

        #Textboxes
        for i,x in ((("tsearchbox",),_("tsearchbox")),
                   ):
            for j in i:
                self.me.get_widget(j).set_text(x)


    def __initialize_combobox2(self):
        combo = self.me.get_widget("combobox2")
        model = combo.get_model()
        if model != None:
            model.clear()
            combo.set_model(None)
        model = gtk.ListStore(gobject.TYPE_STRING)
        combo.set_model(model)
        render = gtk.CellRendererText()

        combo.pack_start(render)
        combo.add_attribute(render, 'text', 0)

        for i in available_langs():
            model.append([i])

    def __initialize_combobox3(self):
        combo = self.me.get_widget("combobox3")
        model = combo.get_model()
        if model != None:
            model.clear()
            combo.set_model(None)
        model = gtk.ListStore(gobject.TYPE_STRING,
                              gobject.TYPE_STRING,
                              gobject.TYPE_STRING,
                              gobject.TYPE_BOOLEAN,
                              )
        combo.set_model(model)
        render = gtk.CellRendererText()

        combo.pack_start(render)
        combo.add_attribute(render, 'text', 0)

        for i in (available_search_engines()):
            model.append(i)

        combo.set_active(0)

    def __initialize_combobox4(self):
        combo = self.me.get_widget("combobox4")
        model = combo.get_model()
        if model != None:
            model.clear()
            combo.set_model(None)
        model = gtk.ListStore(gobject.TYPE_STRING,
                              )
        combo.set_model(model)
        render = gtk.CellRendererText()

        combo.pack_start(render)
        combo.add_attribute(render, 'text', 0)

        for i in ("None, work on local","ssh"):
            model.append([i])

        combo.set_active(0)

    def __changelang(self,*args):
        if self.loading:
            return True
        combo = self.me.get_widget("combobox2")
        tmp = combo.get_model()[combo.get_active()][0].split()
        valor = tmp[-1].replace("(","").replace(")","")
        self.loading = True
        self.__internationalize(lang=valor)
        self.bcontrol.itn()
        self.tcontrol.itn()
        self.__initialize_combobox1()
        while not self.tcontrol.killable:
            sleep(0.2)
        self.options.set("DEFAULT","language",get_locale())
        self.__muestraprefs()
        self.__save_config()
        self.loading = False

    def __initialize_combobox1(self):
        combo = self.me.get_widget("combobox1")
        new = True
        modelp = combo.get_model()
        if modelp != None:
            modelp.clear()
            combo.set_model(None)
            new = False
        model = gtk.ListStore(gobject.TYPE_STRING)
        combo.set_model(model)

        if new:
            render = gtk.CellRendererText()
            combo.pack_start(render)
            combo.add_attribute(render, 'text', 0)

        for i in (_("hiddenbuttons"),_("iconbuttons"),_("labeledbuttons"),_("toolbarbuttons")):
            model.append([i])

    def __changebtnvisibility(self,*args):
        if self.loading:
            valor = self.options.getint("DEFAULT","buttonstyle")
        else:
            valor = self.me.get_widget("combobox1").get_active()
        label = False
        icon = False
        toolbar = False
        if valor==1:
            icon = True
        elif valor == 2:
            label = True
        elif valor == 3:
            toolbar = True
        self.me.get_widget("labeledbuttonbox").set_property("visible",label)
        self.me.get_widget("iconizedbuttonbox").set_property("visible",icon)
        self.me.get_widget("toolbar1").set_property("visible",toolbar)

        if not self.loading:
            self.options.set("DEFAULT","buttonstyle",str(valor))
            self.__save_config()

    def __stopdaemon(self,x=None,y=None,z=None,ufo=False):
        if ufo:
            self.set_startstopdaemon_sensitive(False)
            self.tcontrol.stop_daemon()
            self.statedaemon(False)
            self.stopingstartingdaemon = False
            self.set_startstopdaemon_sensitive(True)
        else:
            if not self.stopingstartingdaemon:
                self.stopingstartingdaemon = True
                kthread(target=self.__stopdaemon,kwargs={"ufo":True}).start()
            

    def __startdaemon(self,x=None,y=None,z=None,ufo=False):
        if ufo:
            self.set_startstopdaemon_sensitive(False)
            self.options_setted = False
            self.tcontrol.start_daemon()
            self.statedaemon(True)
            self.stopingstartingdaemon = False
            self.set_startstopdaemon_sensitive(True)
        else:
            if not self.stopingstartingdaemon:
                self.stopingstartingdaemon = True
                kthread(target=self.__startdaemon,kwargs={"ufo":True}).start()

    def __save_config(self):
        file = open(self.config_file,"w")
        if self.options.getint("DEFAULT","protocol")==1 and \
           not self.options.getboolean("SSH","remenber"):
            passw = self.options.get("SSH","password")
            self.options.set("SSH","password","")
            self.options.write(file)
            self.options.set("SSH","password",passw)
        else:
            self.options.write(file)
        file.close()
        
    def stateconnected(self,state=True):
        if self.stateconnectedbool != state:
            self.stateconnectedbool = state
            self.me.get_widget("menudirectory").set_sensitive(state)
            self.me.get_widget("menudisconnect").set_property("visible",state)
            #self.me.get_widget("menureconnect").set_property("visible",not state)
            self.set_startstopdaemon_sensitive(state)
            if not state:
                self.statedaemon(False)
                self.mainStatus(_("disconnected"))
                
    def set_startstopdaemon_sensitive(self,value=True):
        self.me.get_widget("menuitem3").set_sensitive(value)
        self.me.get_widget("menuitem5").set_sensitive(value)
        
    def statedaemon(self,state=True):
        if self.statedaemonbool != state:
            self.statedaemonbool = state
            self.me.get_widget("notebook2").set_sensitive(state)
            self.me.get_widget("vbox3").set_sensitive(state)
            self.me.get_widget("menuitem3").set_property("visible",not state)
            self.me.get_widget("menuitem5").set_property("visible",state)
            self.tcontrol.enableadd(state)
            if not state:
                self.tcontrol.clearmodel()
                self.mainStatus(_("transmissiondaemonnotrunning"))

    def __disconnect(self,*args):
        self.tcontrol.disconnect()
        self.__remove_connection_config()
        self.options.set("DEFAULT","protocol","-1")
        self.__save_config()
        self.stateconnected(False)


    def __remove_connection_config(self):
        for i in ["SSH"]:
            if self.options.has_section("SSH"):
                self.options.remove_section("SSH")
        self.options.set("DEFAULT","protocol","-1")

    def __muestrabout(self,*args):
        self.me.get_widget("aboutdialog1").show()

    def __aboutresponse(self,widget,id):
        if id in (-6,-4):
            self.me.get_widget("aboutdialog1").hide()
        return True

    def __window1_show(self):
        self.tryexit = False
        self.me.get_widget("window1").show()

    def __window1_hide(self):
        if self.me.get_widget("window1")!=None:
            self.me.get_widget("window1").hide()
        self.tryexit = True
        self.tcontrol.refresh_stop()

    def new_session(self,ip="",user="",passw="",port="",remenber=False,protocol=1):
        a = kthread(target=self.__new_session,
            kwargs={"ip":ip,"user":user,"passw":passw,"port":port,"remenber":remenber,"protocol":protocol}
            )
        text=_("connectinglabel")
        if protocol==1:
            text = _("connectingremotelabel")
        self.ldialog.start(text=text,thread=a)
        a.start()

    def __new_session(self,ip="",user="",passw="",port="",remenber=False,protocol=1):
        self.loading = True
        if protocol == 0:
            tmp = self.tcontrol.c.new_local_session()
        elif protocol == 1:
            tmp = self.tcontrol.c.new_ssh_session(ip,user,passw,port)

        if tmp[1] != None:
            if tmp[0]==0:
                print "Selene transmission needs transmission-remote and transmission-daemon installed in server."
                print "If already installed, check they're accesible by PATH."

            gtk.gdk.threads_enter()
            self.me.get_widget("logindialog").hide()
            gtk.gdk.threads_leave()

            self.options_setted = False
            self.tcontrol.c.protocol = protocol
            self.tcontrol.c.session = tmp[1]
            if protocol == 1:
                self.tcontrol.c.auxsession = self.tcontrol.c.new_ssh_session(ip,user,passw,port,verify=False)[1]
            else:
                self.tcontrol.c.auxsession = None
            
            if protocol==0:
                self.__remove_connection_config()
                self.options.set("DEFAULT","protocol","0")
            elif protocol==1:
                T.ip = ip
                T.user = user
                T.passw = passw
                T.port = int(port)
                if not self.options.has_section("SSH"):
                    self.options.add_section("SSH")
                self.options.set("SSH","host",ip)
                self.options.set("SSH","user",user)
                self.options.set("SSH","password",b64encode(passw))
                self.options.set("SSH","port",str(int(port)))
                self.options.set("SSH","remenber",str(int(remenber)))
                self.options.set("DEFAULT","protocol","1")

            self.options_setted = False
            self.stateconnected(True)
            
            if tmp[2]:
                self.statedaemon(True)
                self.hup(1)
                if len(self.tqueue)>0:
                    self.tcontrol.c.send_torrents(self.tqueue)
                    self.tqueue = []
                self.tcontrol.rowrefresh(exit=False)
            else:
                self.statedaemon(False)
            self.__save_config()
        else:
            self.stateconnected(False)
            self.__logindialog_show(error=_("loginerrormessage"))
        self.loading = False
        self.ldialog.stop()

    def get_prefs(self):
        if not self.options_setted:
            if not self.tcontrol.c.daemon_running()[0]:
                self.me.get_widget("vbox3").set_sensitive(False)
            else:
                commandos = ["file -b $HOME/.transmission/daemon/state",
                             "cat $HOME/.transmission/daemon/state"]
                retorno = self.tcontrol.c.exec_commands(commands=commandos)
                for i in ("error","cannot open"):
                    if i in retorno[0].strip().split(linesep)[0].lower():
                        print "Unable to find transmission daemon config file."
                        self.me.get_widget("configerror").set_property("visible",True)
                        return
                self.me.get_widget("configerror").set_property("visible",False)
                if retorno == None or len(retorno)<2:
                    self.me.get_widget("vbox3").set_sensitive(False)
                else:
                    self.loading = True
                    retorno = retorno[1].strip()
                    if retorno.find("default-directory")!=-1:
                        self.incoming = retorno[retorno.find("default-directory"):].split(":")[1][:-2]
                        self.me.get_widget("opsfolder").set_text(self.incoming)
                    if retorno.find("porti")!=-1:
                        self.me.get_widget("spinbutton1").set_value(
                            float(retorno[retorno.find("porti"):].split(":")[0][len("porti"):-3]))
                    if retorno.find("download-limiti")!=-1:
                        self.me.get_widget("spinbutton2").set_value(
                            float(retorno[retorno.find("download-limiti"):].split(":")[0][len("download-limiti"):-3]))
                    if retorno.find("upload-limiti")!=-1:
                        self.me.get_widget("spinbutton3").set_value(
                            float(retorno[retorno.find("upload-limiti"):].split(":")[0][len("upload-limiti"):-2]))

                    if retorno.rfind("encryption-mode")!=-1:
                        value = retorno[retorno.find("encryption-mode"):].split(":")[1]
                        if "required" in value:
                            self.me.get_widget("checkbutton1").set_active(True)
                        else:
                            self.me.get_widget("checkbutton1").set_active(False)

                    if retorno.rfind("default-pexi")!=-1:
                        value = retorno[retorno.find("default-pexi")+len("default-pexi"):].split(":")[0][:].split("e")[0]
                        if "1" in value:
                            self.me.get_widget("checkbutton2").set_active(True)
                        else:
                            self.me.get_widget("checkbutton2").set_active(False)

                    if retorno.rfind("port-mappingi")!=-1:
                        value = retorno[retorno.find("port-mappingi"):].split(":")[0].split("e")[0]
                        if "1" in value:
                            self.me.get_widget("checkbutton3").set_active(True)
                        else:
                            self.me.get_widget("checkbutton3").set_active(False)
                    self.loading = False
                    self.options_setted = True
                    self.me.get_widget("vbox3").set_sensitive(True)

    def __logindialog_show(self,x=None,y=None,z=None,error=""):

        if len(error)>0:
            self.me.get_widget("loginerror").set_label(error)
            self.me.get_widget("loginerrorbox").show()
        else:
            self.me.get_widget("loginerrorbox").hide()
        self.me.get_widget("logindialog").show()

    def __logindialog_response(self,widget=None,id=0):
        if id == 1:
            a = self.me.get_widget("combobox4").get_active()
            if a==0:
                self.new_session(protocol=a)
            elif a == 1:
                self.new_session(self.me.get_widget("loginhost").get_text(),
                                 self.me.get_widget("loginuser").get_text(),
                                 self.me.get_widget("loginpassw").get_text(),
                                 int(self.me.get_widget("loginport").get_value()),
                                 self.me.get_widget("loginremenber").get_active(),
                                 protocol=a)
        else:
            self.me.get_widget("logindialog").hide()

    def __browseincoming(self,*args):
        if self.tcontrol.get_protocol()==0:
            system("xdg-open "+self.incoming)
        else:
            self.bcontrol.show(path=self.incoming)

    def __statuscheck(self,widget):
        if  self.loading:
            return
        self.options.set("DEFAULT","showtimeout",str(int(widget.get_active())))
        self.__save_config()
        
    def __showsearchbox(self,widget):
        if  self.loading:
            return
        value = int(widget.get_active())
        self.options.set("DEFAULT","showsearchbox",str(value))
        self.me.get_widget("searchbox").set_property("visible",bool(value))
        self.__save_config()

    def __cryptcheck(self,widget):
        if  self.loading:
            return
        valor = "preferred"
        if widget.get_active():
            valor = "required"
        self.__storeopt([self.tcontrol.c.command+" -c"],[self.tcontrol.c.command+" -c "+valor])

    def __pexcheck(self,widget):
        if  self.loading:
            return
        valor = "-E"
        if widget.get_active():
            valor = "-e"
        self.__storeopt([self.tcontrol.c.command+" -e",self.tcontrol.c.command+" -E"],[self.tcontrol.c.command+" "+valor])

    def __upnpcheck(self,widget):
        if  self.loading:
            return
        valor = "-M"
        if widget.get_active():
            valor = "-m"
        self.__storeopt([self.tcontrol.c.command+" -m",self.tcontrol.c.command+" -M"],[self.tcontrol.c.command+" "+valor])

    def __portspin(self,widget):
        if  self.loading:
            return
        self.spinvalues[0] = [[self.tcontrol.c.command+" -p"],[self.tcontrol.c.command+" -p "+widget.get_text()]]
        self.__waitspin()

    def __ldownspin(self,widget):
        if  self.loading:
            return
        value = widget.get_text()
        erase = [self.tcontrol.c.command+" -d", self.tcontrol.c.command+" -D"]
        if int(value)==-1:
            self.spinvalues[1] = [erase,[self.tcontrol.c.command+" -D"]]
        else:
            self.spinvalues[1] = [erase,[self.tcontrol.c.command+" -d "+value]]
        self.__waitspin()

    def __lupspin(self,widget):
        if  self.loading:
            return
        value = widget.get_text()
        erase = [self.tcontrol.c.command+" -u", self.tcontrol.c.command+" -U"]
        if int(value)==-1:
            self.spinvalues[2] = [erase,[self.tcontrol.c.command+" -U"]]
        else:
            self.spinvalues[2] = [erase,[self.tcontrol.c.command+" -u "+value]]
        self.__waitspin()

    def __timeoutspin(self,widget):
        if  self.loading:
            return
        self.spinvalues[3] = [str(int(widget.get_value()*1000))]
        self.__waitspin()
        
    def __sshalivespin(self,widget):
        if  self.loading:
            return
        self.spinvalues[4] = [str(int(widget.get_value()*1000))]
        self.__waitspin()

    def __waitspin(self,ufo = False):
        if  self.loading:
            return
        if ufo:
            while self.pthread_time < self.prop_timeout:
                sleep(0.5)
                self.pthread_time += 500
                #print self.pthread_time,self.prop_timeout

            for i in range(0,3):
                if self.spinvalues[i]!=None:
                     self.__storeopt(self.spinvalues[i][0],self.spinvalues[i][1])
                     self.spinvalues[i] = None
            options = False
            if self.spinvalues[3]!=None:
                self.options.set("DEFAULT","timeout",self.spinvalues[3][0])
                options = True
                
            if self.spinvalues[4]!=None:
                self.options.set("DEFAULT","sshalive",self.spinvalues[4][0])
                options = True
                
                
            if options:
                self.__save_config()

            self.pthread_running = False
        else:
            self.pthread_time = 0
            if self.pthread_running==False:
                self.pthread_running = True
                a = kthread(target=self.__waitspin,kwargs={"ufo":True})
                a.start()

    def __opsfolderclick(self,widget,key):
        if key.button == 1 and key.type == gtk.gdk._2BUTTON_PRESS:
            self.__opsbrowse()
            return True
        return False

    def __storeopt(self,toerase=[],new=[]):
        self.tcontrol.c.store_option(toerase,new)
        if len(self.tcontrol.c.to_set)>0:
            self.me.get_widget("proxcon").set_property("visible",True)

    def __opsbrowse(self,x=None,y=None,z=None,k=None,ufo=False):
        self.bcontrol.show(style=1,path=self.incoming)
    
    def opsbrowseset(self,path=None):
        if path != None and path.strip():
            self.me.get_widget("opsfolder").set_text(path)
            self.manualbrowse_time = 6
            #self.__storeopt([self.tcontrol.c.command+" -f"],[self.tcontrol.c.command+" -f "+path])

    def __opsmanualbrowse(self,x=None,y=None,z=None,k=None,ufo=False):
        if self.loading:
            return
        if ufo:
            while self.manualbrowse_time < 5:
                sleep(1)
                self.manualbrowse_time += 1
            
            retorno = self.me.get_widget("opsfolder").get_text().strip()
            if retorno[-1]=="/" and len(retorno)>1:
                retorno = retorno[:-1]
                self.me.get_widget("opsfolder").set_text(retorno)
            if self.bcontrol.checkfolder(retorno) and retorno != self.incoming:
                self.incoming = retorno
                self.__storeopt([self.tcontrol.c.command+" -f"],[self.tcontrol.c.command+" -f "+retorno])
            else:
                self.me.get_widget("opsfolder").set_text(self.incoming)
            self.manualbrowse_running = False
        else:
            self.manualbrowse_time = 0
            if not self.manualbrowse_running:
                self.manualbrowse_running = True
                a = kthread(target=self.__opsmanualbrowse,kwargs={"ufo":True})
                a.start()

    def __muestraprefs(self,*args):
        self.get_prefs()
        self.loading = True
        self.me.get_widget("spinbutton4").set_value(float(self.options.getint("DEFAULT","timeout"))/1000)
        self.me.get_widget("spinbutton5").set_value(float(self.options.getint("DEFAULT","sshalive"))/1000)
        self.me.get_widget("checkbutton4").set_active(bool(self.options.getint("DEFAULT","showtimeout")))
        self.me.get_widget("checkbutton5").set_active(bool(self.options.getint("DEFAULT","showsearchbox")))
        self.me.get_widget("combobox1").set_active(self.options.getint("DEFAULT","buttonstyle"))

        combo2 = self.me.get_widget("combobox2")
        combo2model = combo2.get_model()
        for i in range(len(combo2.get_model())):
            if combo2model[i][0].split()[-1].replace("(","").replace(")","") == self.options.get("DEFAULT","language"):
                self.me.get_widget("combobox2").set_active(i)
                break
        # combobox2
        self.loading = False


        self.me.get_widget("window2").show()

    def __destroyevent(self,widget,data):
        widget.hide()
        return True

    def __opscerrar(self,*args):
        self.pthread_time = self.prop_timeout +1
        self.me.get_widget("window2").hide()

    def __selector(self,*args):
        selector = gtk.FileChooserDialog(title=_("addtorrentdialog"),
                                         parent=self.me.get_widget("window1"),
                                         action=gtk.FILE_CHOOSER_ACTION_OPEN,
                                         buttons=(gtk.STOCK_CANCEL,0,gtk.STOCK_ADD,1), backend=None)
        selector.set_select_multiple(True)
        filter1 = gtk.FileFilter()
        filter1.set_name(_("bittorrentfile"))
        filter1.add_mime_type("application/x-bittorrent")
        selector.set_filter(filter1)
        selector.connect("response",self.__seleccionado)
        selector.show()

    def __seleccionado(self,widget,id):
        widget.hide()
        if id:
            self.tcontrol.c.send_torrents(widget.get_filenames())
        widget.destroy()

    def mainStatus(self,message=""):
        '''Shows info on main statusbar'''
        if self.stid != None:
            self.me.get_widget("statusbar1").remove(self.stcontext, self.stid)
            self.stid = None

        if len(message)>0:
            self.stid = self.me.get_widget("statusbar1").push(self.stcontext, message)

    def __start(self,*args):
        commands = []
        for i in self.tcontrol.selected_hashes(state=(0,)):
            commands.append(self.tcontrol.c.command+" -s %s" % i)
        self.tcontrol.c.to_exec += commands

    def __pause(self,*args):
        commands = []
        for i in self.tcontrol.selected_hashes(state=(-1,1,2,3)):
            commands.append(self.tcontrol.c.command+" -S %s" % i)
        self.tcontrol.c.to_exec += commands

    def __askremove(self,*args):
        ask = gtk.MessageDialog(parent=self.me.get_widget("window1"),
                                flags=gtk.DIALOG_MODAL,
                                type=gtk.MESSAGE_QUESTION ,
                                buttons=gtk.BUTTONS_YES_NO,
                                message_format=_("removedialoginfo"))
        ask.set_title(_("removedialog"))
        ask.connect("response",self.__remove)
        ask.show()

    def __remove(self,widget,id):
        widget.hide()
        if id==-8:
            commands = []
            for i in self.tcontrol.selected_hashes():
                commands.append(self.tcontrol.c.command+" -r %s" % i)
            self.tcontrol.c.to_exec += commands
        widget.destroy()

    def hup(self,signum,stack=None):
        if exists(tqfile) and isfile(tqfile):
            f = open(tqfile,"r")
            tmp = f.readlines()
            f.close()
            for i in tmp:
                if exists(i) and isfile(tqfile):
                    self.tqueue.append(i)
            remove(tqfile)
        self.me.get_widget("window1").set_urgency_hint(True)
        #self.tcontrol.refresh_now()
        #self.__window1_show()

    def __torrentsearchbutton(self,*args):
        a = self.me.get_widget("tsearchbox").get_text()
        if len(a)>0:
            self.torrentsearcher(a)
            self.tsearchboxeraseable = True
            self.me.get_widget("tsearchbox").set_text(_("tsearchbox"))

    def torrentsearcher(self,text=""):
        combo = self.me.get_widget("combobox3")
        row = combo.get_model()[combo.get_active()]
        text = text.replace(" ",row[2])
        if not row[3]:
            for i,j in (("á","a"),("é","e"),("í","i"),("ó","o"),("ú","u")):
                text = text.replace(i,j)
        open_browser(row[1].replace("%s",text))

    def __quit(self,*args):
        self.__window1_hide()
        self.me.get_widget("logindialog").hide()
        self.tcontrol.disconnect()
        self.bcontrol.kill = True
        gtk.main_quit()

def singleinstance():
    '''Check if other selenetransmission is running'''
    running = False
    pidPath = configfolder+sep+"gui.lock"
    if exists(pidPath):
        f = open(pidPath, 'r')
        pid=f.read().strip()
        f.close()
        pidRunning=getoutput('ps --pid %s |grep %s' % (pid,pid,)).strip()

        if pidRunning:
            running = True

    if not running:
        fp=open(pidPath, 'w')
        fp.write(str(getpid()))
        fp.close()
        return -1
    else:
        return int(pid)

def usage():
    print "Usage is:"
    print "\tselenetransmissiongui.py [options] [file1,file2, ...]"
    print "Start gui:"
    print "\tselenetransmissiongui.py"
    print "For sending files to remote transmission-daemon:"
    print "\tselenetransmissiongui.py [file1,file2, ...]"
    print "Options:"
    print "\t-h --help prints this help and exits."
    print "\t-v --version prints program version and exits."

# Config
apppath = realpath(path_split(argv[0])[0])
gladefile = apppath + sep + "gui.glade"
set_langfolder(apppath + sep + get_langfolder())
set_tsearchfolder(apppath + sep + get_tsearchfolder())


configfolder = expandvars("$HOME/.config/selenetransmission")
tqfile = configfolder+sep+"tqueue"

if __name__== "__main__":
    if not exists(configfolder):
        mkdir(configfolder)
    try:
        optlist, args = getopt.getopt(argv[1:],"hv",["help","version"])
        for i,x in optlist:
            if i in ("-h","--help"):
                usage()
                exit(0)
            elif i in ("-v","--version"):
                print "Version: "+str(__version__)
                sys_exit(0)

        torrentfiles = []

        for i in args:
            if i[:7] == "file://":
                i = url2pathname(i[7:])
            if exists(i):
                torrentfiles.append(realpath(i))

        pid = singleinstance()
        if pid == -1:
            #system('zenity --info --text="'+str(argv)+" "+str(torrentfiles)+'"')
            gtk.gdk.threads_init()
            main = Main()
            signal(1, main.hup)
            main.tqueue = torrentfiles
            gtk.main()
        else:
            if len(torrentfiles)>0:
                if exists(tqfile):
                    f = open(tqfile,"a")
                    f.writelines(torrentfiles)
                    f.close()
                else:
                    f = open(tqfile,"w")
                    f.writelines(torrentfiles)
                    f.close()
            kill(pid, 1) # send hup signal
    except:
        dnt = " "*4
        extra_info = "None"
        i = exc_info()
        if i[2]!=None:
            extra_info = ""
            k = extract_tb(i[2])
            total = len(k)
            for j in range(total):
                extra_info += "%sLevel %d of %d\n" % (dnt*2,j+1,total)
                tmp = dnt*3
                extra_info += tmp + "File: " + str(k[j][0]) + "\n"
                extra_info += tmp + "Line: "+str(k[j][1])+"\n"
                extra_info += tmp + "Section: "+str(k[j][2])+"\n"
            extra_info = extra_info[:-1]
        
        text = "Called by: %s\nException info:\n%s%s: %s\n%s" % (str(argv),dnt, str(i[0].__name__),str(i[1]),extra_info)
        print text
        kill(getpid(), 9)
        #sys_exit(0)
        #system('python '+ apppath + sep + 'bug.py """'+text+'""" '+argv[0])

sys_exit(0)
